﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MuseLibrary.EncodingHelpers
{
    public class QuotientParser
    {
        public QuotientParser()
        {
            _array = new List<bool>(15);
        }

        public void ResetState()
        {
            _array.Clear();
            _quotient = 0;
            _encoding = BitEncoding.Unary;
            _leadingZeros = 0;
        }

        private List<bool> _array;
        private BitEncoding _encoding = BitEncoding.Unary;
        private int _quotient = 0;
        private int _leadingZeros = 0;

        public int Quotient
        {
            get { return _quotient; }
        }

        public bool ReadBit(bool bit)
        {
            switch (_encoding)
            {
                case BitEncoding.Unary:
                    if (!bit)
                    {
                        if (_array.Count() <= 14)
                        {
                            _quotient = _array.Count;
                            return true;
                        }
                        else
                        {
                            _array.Clear();
                            _array.Add(bit);
                            _encoding = BitEncoding.Elias;
                            return false;
                        }
                    }

                    _array.Add(bit);
                    break;

                case BitEncoding.Elias:
                    if (_leadingZeros == 0 && bit)
                    {
                        _leadingZeros = _array.Count;
                    }

                    _array.Add(bit);
                    if (_leadingZeros != 0 && _array.Count == (2 * _leadingZeros) + 1)
                    {
                        _quotient = _array.ToElias(_leadingZeros);
                        return true;
                    }

                    break;
            }

            return false;
        }
    }
}
